﻿// 编译环境：Visual C++ 6.0~2022，EasyX_20240601
// https://easyx.cn
//
#include <graphics.h>
#include <time.h>
#include <conio.h>
#include <stdio.h>
#include <math.h>

struct BALL
{
	double	x;
	double y;
	double direction;
	double speed;
} ball;

const double BALL_RADIUS = 3.0;
const double PI = 3.1415926535897;

const double TABLE_HEIGHT = 480;
const double TABLE_WIDTH = 640;

struct PLAYER
{
	double x;
	double y;
	int score;
} p1, p2;

int server = rand() > RAND_MAX / 2 ? 1 : 2;

void InitBall()
{
	ball.x = 320;
	ball.y = 240;
	ball.direction = 0.2 * PI * (1.0 - 1.0 * rand() / RAND_MAX) + ( PI * (server-1) );   // 如果server=2，向左发球
	ball.speed = 4;
}

// 移动小球。
// 返回
// 0表示球在界内；
// 1表示玩家1没有接到球
// 2表示玩家2没有接到球
int MoveBall()
{
	setlinecolor(BLACK);
	setfillcolor(BLACK);
	fillcircle(ball.x, ball.y, 3);

	ball.x += cos(ball.direction) * ball.speed;
	ball.y += sin(ball.direction) * ball.speed;

	if (ball.x > 640) {
		p1.score = p1.score + 1;
		server = 1;
		return 2;
	}

	if (ball.x < 0) {
		p2.score = p2.score + 1;
		server = 2;
		return 1;
	}

	if (ball.y < BALL_RADIUS) {
		ball.direction = 2 * PI - ball.direction;
	}

	if (ball.y > TABLE_HEIGHT - BALL_RADIUS) {
		ball.direction = 2 * PI - ball.direction;

	}

	if (ball.x < 90 && fabs(ball.y - p1.y) < 20 ) {
		ball.direction = PI - ball.direction;
	}

	if (ball.x > 550 && fabs(ball.y - p2.y) < 20) {
		ball.direction = PI - ball.direction;
	}

	setlinecolor(WHITE);
	setfillcolor(WHITE);
	fillcircle(ball.x, ball.y, BALL_RADIUS);

	return 0;
}

void DrawPlayer(int id, COLORREF color)
{
	setlinecolor(color);
	setfillcolor(color);
	if (id == 1) {
		fillrectangle(p1.x - 2, p1.y - 20, p1.x + 2, p1.y + 20);
	}
	else {
		fillrectangle(p2.x - 2, p2.y - 20, p2.x + 2, p2.y + 20);

	}

}

void DrawResult()
{
	settextstyle(32, 0, _T("Arial"));
	wchar_t s1[] = L"GAME OVER";
	outtextxy(240, 200, s1);

}


void DrawScore()
{
	wchar_t s1[] = L"00";
	wchar_t s2[] = L"00";
	settextstyle(64, 0, _T("Arial"));

	_stprintf_s(s1, _T("%d"), p1.score);
	outtextxy(200, 100, s1);

	_stprintf_s(s2, _T("%d"), p2.score);
	outtextxy(400, 100, s2);
}

bool isGameOver = false;
bool quit = false;

// 主函数
int main()
{
	srand((unsigned)time(NULL));	// 随机种子
	initgraph(640, 480, EX_SHOWCONSOLE);			// 创建绘图窗口

	while (!quit) {

		// 初始化屏幕
		cleardevice();
		 
		// 初始化小球
		InitBall();

		// 初始化玩家
		p1.x = 80;
		p1.y = 240;

		p2.x = 560;
		p2.y = 240;

		DrawPlayer(1, WHITE);
		DrawPlayer(2, WHITE);

		ExMessage m;		// 定义消息变量
		bool inRange = true;
		while (inRange)
		{
			// 获取一条按键消息
			bool ret = peekmessage(&m, EX_CHAR, true);

			if (ret == true)
			{
				printf("%d", m.ch);
				switch (m.ch)
				{

				case 'i':
					DrawPlayer(2, BLACK);
					p2.y -= 15;
					p2.y = max(0, p2.y);
					DrawPlayer(2, WHITE);
					break;

				case 'k':
					DrawPlayer(2, BLACK);
					p2.y += 15;
					p2.y = min(480, p2.y);
					DrawPlayer(2, WHITE);
					break;

				case 'w':
					DrawPlayer(1, BLACK);
					p1.y -= 15;
					p1.y = max(0, p1.y);
					DrawPlayer(1, WHITE);
					break;

				case 's':
					DrawPlayer(1, BLACK);
					p1.y += 15;
					p1.y = min(480, p1.y);
					DrawPlayer(1, WHITE);
					break;

				}
			}

			ret = MoveBall();
			if (ret != 0) {
				printf("out of range\n");
				inRange = false;
			}
			Sleep(20);
		}

		if ( p1.score >= 11 || p2.score >= 11) {
			isGameOver = true;
			DrawResult();
		}

		DrawScore();
		getmessage(EX_CHAR);
		
		if (isGameOver) {
			p1.score = 0;
			p2.score = 0;
			isGameOver = false;
		}
	}

	closegraph();					// 关闭绘图窗口
	return 0;
}
